package com.example.webdemo;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.activity.ComponentActivity;
import com.example.webdemo.utils.LogUtil;
import com.example.webdemo.widget.WebViewProgressBar;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WebViewActivity extends ComponentActivity implements View.OnClickListener {
    private RelativeLayout rlWebContainer;
    private WebView webView;
    private WebViewProgressBar progressBar;

    public static final String TITLE = "title";
    public static final String URL = "url";

    private String webUrl = "";
    private String title = "";

    private ImageView webBack;
    private TextView webTitle, tvEmpty;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);
        webUrl = getIntent().getExtras().getString(URL);
        title = getIntent().getExtras().getString(TITLE);
        initView();
        setListener();
        setActivityTitle(title);
    }

    public void initView() {
        rlWebContainer = findViewById(R.id.rl_web_container);
        webView = findViewById(R.id.act_webView);
        progressBar = findViewById(R.id.activity_webview_progressbar);
        webBack = findViewById(R.id.wv_back);
        webTitle = findViewById(R.id.wv_title);
        tvEmpty = findViewById(R.id.tv_empty);
    }

    /**
     * 设置页面标题
     */
    public void setActivityTitle(String title) {
//        mRootView.showTitle(title);
    }

    private void setWebTitle(String title) {
        webTitle.setText(title);
    }


    public void setListener() {
        tvEmpty.setOnClickListener(this);
        webBack.setOnClickListener(this);
        initWebSettings(webView);
        webView.setWebChromeClient(new WebChromeClientRingTone());
        webView.setWebViewClient(new WebViewClientRingTone());
        webView.requestFocus();
        webView.setOnCreateContextMenuListener(this);
        webView.setFocusable(true);
        webView.loadUrl(webUrl);
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initWebSettings(WebView webView){
        WebSettings webSetting = webView.getSettings();
        // 支持JavaScript
        webSetting.setJavaScriptEnabled(true);
        // 设置可以访问文件s
        webSetting.setAllowFileAccess(true);
        // 告诉javascript来自动打开的窗口。这适用于JavaScript函数的窗口，open()。
        webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
        // 支持缩放
        webSetting.setSupportZoom(true);
        // 是否禁止是网络加载数据
        webSetting.setBlockNetworkLoads(false);
        // 设置是否支持多窗口
        webSetting.setSupportMultipleWindows(true);
        // 是否开启本地DOM存储
        webSetting.setDomStorageEnabled(true);
        // 设置不缓存
        webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
        // 阻塞加载图片
        webSetting.setBlockNetworkImage(false);
        // 支持启用插件
        webSetting.setPluginState(WebSettings.PluginState.ON);

        //网页超出屏幕大小的处理
        webSetting.setUseWideViewPort(true);
        webSetting.setLoadWithOverviewMode(true);

        // 控制页面显示布局
        // NARROW_COLUMNS：可能的话使所有列的宽度不超过屏幕宽度
        // NORMAL：正常显示不做任何渲染
        // SINGLE_COLUMN：把所有内容放大webview等宽的一列中
        webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        //禁止用地理定位
        webSetting.setSaveFormData(true);
        // 是否启动地理定位
        webSetting.setGeolocationEnabled(true);
        // 设置定位的数据库路径
        webSetting.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // 大于21
            webSetting.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
    }

    public WebView newWebView = null;

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.wv_back){
            if (webView.canGoBack()) {
                webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
                webView.goBack();
            } else {
                finish();
            }
        } else if (v.getId() == R.id.tv_empty) {
            tvEmpty.setVisibility(View.GONE);
            webView.loadUrl(webUrl);
        }
    }

    private class WebChromeClientRingTone extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            return super.onJsAlert(view, url, message, result);
        }

        //处理js打开新标签页的问题：重载onCreateWindow方法实现js的window.open
        @Override
        public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
            newWebView = new WebView(view.getContext());
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
            newWebView.setLayoutParams(layoutParams);
            rlWebContainer.addView(newWebView);
            initWebSettings(newWebView);
            newWebView.setWebViewClient(new WebViewClientRingTone()); //否则window.open弹出在浏览器中打开
            newWebView.setWebChromeClient(this);
            ((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);
            resultMsg.sendToTarget();
            return true;
        }

        //重载onCloseWindow方法实现js的window.close
        @Override
        public void onCloseWindow(WebView view) {
            if (newWebView != null) {
                newWebView.setVisibility(View.GONE);
                view.removeView(newWebView);
            }
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            progressBar.setProgress(newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            WebViewActivity.this.title = title;
            if (isContainChinese(title)) {
//                setWebTitle(title);
                setActivityTitle(title);
            } else {
                setWebTitle("");
            }
        }
    }

    //判断是否存在汉字
    public boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    private class WebViewClientRingTone extends WebViewClient {
        private boolean isRedirect = false; //是否是重定向
        private boolean isPageOk = false; //目的地地址加载完成

//        public boolean shouldOverrideUrlLoading(WebView view, String urls) {
//            LogUtil.d("@@@==== shouldOverrideUrlLoading() ===");
////            isRedirect = false;
////            if (isPageOk) {
////                view.loadUrl(urls);
////                return true;
////            }
//            return false;
//        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            LogUtil.d("@@@=== onPageStarted() ===url: "+url);
            isRedirect = true;
            isPageOk = false;
            progressBar.setVisibility(View.VISIBLE);
        }

        @SuppressLint({"JavascriptInterface", "NewApi"})
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            LogUtil.d("@@@=== onPageFinished() ===Progress: "+view.getProgress()+", url: "+url);
            isPageOk = isRedirect;
            progressBar.setVisibility(View.GONE);
        }

        public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) {
            final SslErrorHandler mHandler;
            mHandler = handler;
            AlertDialog.Builder builder = new AlertDialog.Builder(WebViewActivity.this);
            builder.setMessage("ssl证书验证失败");
            builder.setPositiveButton("继续", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mHandler.proceed();
                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mHandler.cancel();
                }
            });
            builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                        mHandler.cancel();
                        dialog.dismiss();
                        return true;
                    }
                    return false;
                }
            });
            AlertDialog dialog = builder.create();
            dialog.show();
        }

        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            super.onReceivedHttpError(view, request, errorResponse);
            int statusCode = errorResponse.getStatusCode();
            if (500 == statusCode) {
                view.loadUrl("about:blank");// 避免出现默认的错误界面
                tvEmpty.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            LogUtil.d("@@@==== onReceivedError(), error: "+error.getErrorCode()+", "+error.getDescription());
            if (request.isForMainFrame()) {//是否是为 main frame创建
                view.loadUrl("about:blank");// 避免出现默认的错误界面
                tvEmpty.setVisibility(View.VISIBLE);
            }

        }
    }

    @Override
    public void onBackPressed() {
        LogUtil.d("CCC == webView.canGoBack() --> "+webView.canGoBack());
        if (null != newWebView) {
            LogUtil.d("CCC == newWebView.canGoBack() --> "+newWebView.canGoBack());
            if (newWebView.canGoBack()) {
                newWebView.goBack();
            } else{
                destroyNewWeb();
            }
        } else
            if (null != webView && webView.canGoBack()) {
            webView.goBack();
        } else {
            LogUtil.d("CCC == super.onBackPressed() ---");
            super.onBackPressed();
        }
    }

    private void destroyNewWeb(){
        if (newWebView != null) {
            newWebView.clearCache(true);
            newWebView.clearHistory();
            rlWebContainer.removeView(newWebView);
            newWebView.destroy();
            newWebView = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        destroyNewWeb();
        if (webView != null) {
            webView.clearCache(true);
            webView.clearHistory();
            ((ViewGroup) webView.getParent()).removeView(webView);
            webView.destroy();
        }
    }

}
